# !/usr/bin/env python
# encoding: utf-8
'''
  @author: HJW
  @license: (C) Copyright 2013-2017, Node Supply Chain Manager Corporation Limited.
  @contact: hejunwang01@126.com
  @file: netty_recv.py
  @time: 2023/9/24 0024 下午 16:39
  @desc:
  '''
import json
import sys
import threading
import time
from socket import *

from jsonpath import jsonpath

from mydb import MySqlDb

_BUFSIZE = 1024
SECS = 1

g_var = 0
g_mngSN = 0
g_mngId = ""
g_dcode = ""
g_message_list = []
g_door_status = ""
g_op = "-1"
g_moduleId = ""
g_sessionId = ""


def bytetostr(by):
    return str(by, encoding="utf-8")


class NettyThread(threading.Thread):

    def __init__(self, content):
        super(NettyThread, self).__init__()
        self.mngid = str.split(content, ',')[0]
        self.device_type = str.split(content, ',')[1]
        print(f"mngid-->{self.mngid},device_type-->{self.device_type} ")
        self.db = MySqlDb()

        with open('config.json', 'r', encoding='utf-8') as fp:
            json_data = fp.read()
            json_data = json.loads(json_data)
            host = jsonpath(json_data, "$.testsss.nettyadd.host")
            port = jsonpath(json_data, "$.testsss.nettyadd.port")
        try:
            self.netty_client = socket(AF_INET, SOCK_STREAM)
            _ADDR = (host[0], port[0])
            self.netty_client.connect(_ADDR)
            print(f'Connect Server Success :{self.netty_client}')

            # netty 不同设备类型  柜 ，桩
            if self.device_type == "40":
                self.reg_device_b40(self.mngid)

            elif self.device_type == "10":
                self.reg_device_g15(self.mngid)

        except Exception as e:
            print(f'Failed to connect to Server; {e} !!!')
            sys.exit(1)

    def Heartbeat(self):
        # 心跳发送
        i = 0
        while True:
            time.sleep(1)
            i += 1
            payload = {"msgSN": 0}
            data = json.dumps(payload) + "\r\n"
            if i == 20:
                self.netty_client.send(str.encode(data))
                print(f'send Heartbeat test delay {i}')
                i = 0

    def run(self):
        global g_var, g_mngSN, g_mngId, g_dcode, g_message_list, g_door_status, g_op, g_moduleId, g_sessionId
        global starttime3

        # 心跳测试
        threading.Thread(target=self.Heartbeat, name="Heartbeat", daemon=True).start()

        while True:
            print("等待消息 message >>>")
            recv = self.netty_client.recv(_BUFSIZE)
            time.sleep(2)

            if len(recv) > 0:
                # 注册消息后收到的消息进行解析 ，
                print(f"接收到信息 ：{recv}")
                msg = bytetostr(recv)
                if msg.startswith("{") and "boxCode" in msg:
                    msg = json.loads(msg)
                    boxCode = msg['data']['boxCode']
                    sql = "select * from t_charge_pile where boxCode=" + '"' + str(boxCode) + '"' + " limit 1;"

                    print(f"SQL 查询SQL :{sql}")
                    ress = self.db.select_sql(sql)
                    print(ress)
                    if ress:
                        mngid = ress[0]['mngId']
                        model = ress[0]['model']
                        print(f'mngid--> :{mngid} ,model--->:{model}')
                    else:
                        print("SQL数据库中没有这个设备...")

                elif msg.startswith("req=10002") and "door" in msg:

                    g_message_list = msg.split('&')
                    print(f" 柜接收到消息 ：'{g_message_list}\n' ")
                    g_dcode = (g_message_list[7].split('=', 1))[1]
                    g_op = (g_message_list[2].split('=', 1))[1]
                    msgSN = g_message_list[6][6:]
                    g_mngId = (g_message_list[-1].split(' ', 1))[0]
                    g_moduleId = g_message_list[5]
                    g_sessionId = g_message_list[7]
                    g_door_status = (g_message_list[8].split('=', 1))[1]
                    print("操作类型op:", g_op)
                    # 下单的情况
                    if g_op == '1' and g_door_status == '0':
                        print('recive server request message,door =0')
                        '''
                        'req=10002?sign=sign&pileType=7060&operation=1&maxElectricity=0&maxChargeTime=0&moduleId=4e751cff44172&msgSN=106&sessionId=0000000325028109&door=0&code=-1&pp=0&mngId=4e751cff4417
                        '''
                        print(f'下单前的前置操作..g_op:{g_op},g_door_status:{g_door_status}')
                        g_mngSN = int(msgSN)
                        payload = {"errorCode": 1, "msgSN": g_mngSN}
                        # 一定要加\r\n 代表结束
                        data = json.dumps(payload) + "\r\n"
                        self.netty_client.send(str.encode(data))


                    elif g_op == '1' and g_door_status == '1':
                        print('recive server request message ,door =1')

                        '''
                         'req=10002?sign=sign&pileType=7060&operation=1&maxElectricity=0&maxChargeTime=0&moduleId=4e751cff44172&msgSN=107&sessionId=0000000325028109&door=1&code=-1&pp=0&mngId=4e751cff4417
                        '''

                        print(f'netty柜处理下单的操作..g_op:{g_op},g_door_status:{g_door_status}')
                        g_mngSN = int(msgSN)
                        payload = {"errorCode": 1, "msgSN": g_mngSN}
                        data = json.dumps(payload) + "\r\n"
                        self.netty_client.send(str.encode(data))

                        #  req=10010?msgSN=12&mngId=4e751cff4417&dcode=0000000325028109&power=0&start=1702090819&end=1702090819&index=0&sign=6106
                        # 发送10010
                        starttime = str(int(time.time()))
                        g_mngSN += 1
                        payload = "req=10010?msgSN=" + str(
                            g_mngSN) + "&" + g_mngId.strip() + "&dcode=" + g_dcode + "&power=0&start=" + starttime + "&end=" + starttime + "&index=0&sign=c8ae" + "\r\n"
                        self.netty_client.send(str.encode(payload))
                        print(f"Sending request power-report :{str.encode(payload)}")

                        # 发送102
                        sql = "select * from t_charge_module_device where moduleId=" + '"' + str(
                            (g_message_list[5].split('=', 1))[1]) + '"' + " limit 1;"
                        ress = self.db.select_sql(sql)
                        g_mngSN += 1

                        # req=102?msgSN=13&mngId=4e751cff4417&mcode=6202742&dcode=0000000325028109&status=WAITING&cv=1954&current=10&pwm=0&ele=0&temp=27.38&dsc=NEW_STA#41#29&sign=4a65
                        payload = "req=102?msgSN=" + str(g_mngSN) + "&" + g_mngId.strip() + "&mcode=" + str(
                            ress[0]["moduleCode"]) + "&dcode=" + \
                                  g_dcode + "&status=WAITING&cv=1957&current=2&pwm=0&ele=0&temp=28.81&dsc=NEW_STA#42#30&sign=b978" + "\r\n"

                        self.netty_client.send(str.encode(payload))
                        print(f"Sending request status-report :{str.encode(payload)}")
                        time.sleep(SECS)

                        # req=10010?msgSN=14&mngId=4e751cff4417&dcode=0000000325028109&power=0&start=1702090820&end=1702090820&index=0&sign=c150
                        g_mngSN += 1
                        starttime2 = str(int(time.time()))
                        payload = "req=10010?msgSN=" + str(
                            g_mngSN) + "&" + g_mngId.strip() + "&dcode=" + g_dcode + "&power=0&start=" + starttime2 + "&end=" + starttime2 + "&index=0&sign=c8ae" + "\r\n"
                        # 不要加\r\n
                        self.netty_client.send(str.encode(payload))
                        print(f"Sending request power-report:{str.encode(payload)}")
                        # req=102?msgSN=15&mngId=4e751cff4417&mcode=6202742&dcode=0000000325028109&status=WAITING&cv=1959&current=11&pwm=0&ele=0&temp=27.38&dsc=NEW_STA#41#29&sign=376d
                        g_mngSN += 1
                        payload = "req=102?msgSN=" + str(g_mngSN) + "&" + g_mngId.strip() + "&mcode=" + str(
                            ress[0]["moduleCode"]) + "&dcode=" + \
                                  g_dcode + "&status=WAITING&cv=1957&current=2&pwm=0&ele=0&temp=28.81&dsc=NEW_STA#42#30&sign=b978" + "\r\n"

                        self.netty_client.send(str.encode(payload))
                        print(f"Sending request status-report:{str.encode(payload)}")
                        time.sleep(SECS)

                        print("连接上电池，准备上报充电数据")
                        # sending request charger-report: req=101?msgSN=17&mngId=4e751cff4417&moduleId=4e751cff44172&sessionId=0000000325028109&status=3&electricityConsumption=0&chargeTime=0&sign=e1a8
                        g_mngSN += 1
                        payload = "req=101?msgSN=" + str(
                            g_mngSN) + "&" + g_mngId.strip() + "&" + g_moduleId.strip() + "&" + g_sessionId.strip() + "&status=3&electricityConsumption=0&chargeTime=0&sign=5a1c" + "\r\n"

                        self.netty_client.send(str.encode(payload))
                        print(f"sending request charger-report:{str.encode(payload)}")

                        # sending request : req=103?msgSN=18&mngId=4e751cff4417&moduleId=4e751cff44172&dcode=0000000325028109&type=0000&chargeTime=0&btvol=36&status=-1&sign=cb09
                        # g_mngSN += 1
                        # payload = "req=103?msgSN=" + str(
                        #     g_mngSN) + "&" + g_mngId.strip() + "&" + g_moduleId.strip() + "&dcode=" + g_dcode + "&type=0000&chargeTime=0&btvol=36&status=-1&sign=cb09" + "\r\n"
                        # self.netty_client.send(str.encode(payload))
                        # print(f"sending request detect-report:{str.encode(payload)}")
                        # time.sleep(SECS)

                        # req=102?msgSN=19&mngId=4e751cff4417&mcode=6202742&dcode=0000000325028109&status=WAITING&cv=37606&current=11&pwm=0&ele=0&temp=27.44&dsc=CLOSE_DOOR#41#29&sign=5f52
                        g_mngSN += 1
                        payload = "req=102?msgSN=" + str(g_mngSN) + "&" + g_mngId.strip() + "&mcode=" + str(
                            ress[0]["moduleCode"]) + "&dcode=" + \
                                  g_dcode + "&status=WAITING&cv=37606&current=11&pwm=0&ele=0&temp=27.44&dsc=CLOSE_DOOR#41#29&sign=5f52" + "\r\n"

                        self.netty_client.send(str.encode(payload))
                        print(f"sending request status-report:{str.encode(payload)}")

                        #  req=104?msgSN=25&mngId=4e751cff4417&moduleId=4e751cff44172&sessionId=0000000325028109&doorStatus=0&b_c=1&sign=95d4
                        g_mngSN += 1
                        payload = "req=104?msgSN=" + str(
                            g_mngSN) + "&" + g_mngId.strip() + "&" + g_moduleId.strip() + "&" + g_sessionId.strip() + "&doorStatus=0&b_c=1&sign=a905" + "\r\n"

                        self.netty_client.send(str.encode(payload))
                        print(f"sending request door_state_report:{str.encode(payload)}")


                    elif g_op == '0':
                        #  'req=10002?sign=sign&pileType=7060&operation=0&maxElectricity=0&maxChargeTime=0&moduleId=4e751cff44172&msgSN=108&sessionId=0000000325028109&door=1&code=-1&pp=0&mngId=4e751cff4417
                        print(f'处理关单的操作g_op...{g_op}')
                        print(f'mngSn:{msgSN}')
                        if msgSN:
                            g_mngSN = int(msgSN)
                            payload = {"errorCode": 1, "msgSN": g_mngSN}
                            data = json.dumps(payload) + "\r\n"
                            self.netty_client.send(str.encode(data))
                            print(f"sending response:{str.encode(data)}")

                        else:
                            msgSN = 0
                            g_mngSN = int(msgSN)
                            payload = {"errorCode": 1, "msgSN": g_mngSN}
                            data = json.dumps(payload) + "\r\n"
                            self.netty_client.send(str.encode(data))
                            print(f"Sending response:{str.encode(data)}")

                            # 一定要加\r\n 代表结束
                            print(f"处理的关单:{data}")


                        # req=102?msgSN=27&mngId=4e751cff4417&mcode=6202742&dcode=0000000325028109&status=INITIAL&btvol=37782&temp=27.44&dsc=TERM_EX#41#29&sign=32fb
                        g_mngSN += 1
                        sql = "select * from t_charge_module_device where moduleId=" + '"' + str(
                            (g_message_list[5].split('=', 1))[1]) + '"' + " limit 1;"
                        ress = self.db.select_sql(sql)
                        payload = "req=102?msgSN=" + str(g_mngSN) + "&" + g_mngId.strip() + "&mcode=" + str(
                            ress[0][
                                "moduleCode"]) + "&dcode=" + g_dcode + "&status=INITIAL&btvol=37782&temp=27.44&dsc=TERM_EX#41#29&sign=32fb" + "\r\n"

                        self.netty_client.send(str.encode(payload))
                        print(f"send status-report:{str.encode(payload)}")
                        time.sleep(SECS)

                        g_mngSN += 1
                        # req=101?msgSN=28&mngId=4e751cff4417&moduleId=4e751cff44172&sessionId=0000000325028109&status=6&electricityConsumption=0&chargeTime=70&sign=1927
                        payload = "req=101?msgSN=" + str(
                            g_mngSN) + "&" + g_mngId.strip() + "&" + g_moduleId.strip() + "&" + g_sessionId.strip() + \
                                  "&status=6&electricityConsumption=0&chargeTime=70&sign=1927" + "\r\n"
                        self.netty_client.send(str.encode(payload))
                        print(f"sending request charger-report:{str.encode(payload)}")

                        g_mngSN += 1
                        payload = "req=10010?msgSN=" + str(
                            g_mngSN) + "&" + g_mngId.strip() + "&dcode=" + g_dcode + "&power=12&start=" + str(
                            int(time.time())) + "&end=" + str(int(time.time())) + "&index=1&sign=c8ae" + "\r\n"
                        self.netty_client.send(str.encode(payload))
                        print(f"sending request power-report :{str.encode(payload)}")


                elif msg.startswith('req=10002'):
                    '''
                    # 桩的操作  ['req=10002?sign=sign', 'pileType=6048', 'operation=1', 
                    'maxElectricity=0', 'maxChargeTime=0', 'moduleId=00037f1b00763', 
                    'msgSN=142', 'sessionId=0000000325001043', 'mngId=00037f1b0076\r\n']
                    '''
                    z_message_list = msg.split('&')
                    print(f"充电桩接收到消息 ：'{z_message_list}\n' ")
                    z_dcode = (z_message_list[7].split('=', 1))[1]
                    z_op = (z_message_list[2].split('=', 1))[1]
                    msgSN = z_message_list[6][6:]
                    z_mngId = (z_message_list[-1].split(' ', 1))[0]
                    z_moduleId = z_message_list[5]
                    z_sessionId = z_message_list[7]
                    z_mngId_all = z_message_list[-1]

                    print(f"要操作的类型：{z_op}")
                    '''
                     'req=10002?sign=sign&pileType=7048&operation=1&maxElectricity=0&maxChargeTime=0&moduleId=00037f1049051&msgSN=65&sessionId=0000000325025742&mngId=00037f104905
                    '''
                    # 下单的情况
                    if z_op == '1':
                        z_mngSN = int(msgSN)
                        payload = {"errorCode": 1, "msgSN": z_mngSN}
                        # 一定要加\r\n 代表结束
                        data = json.dumps(payload) + "\r\n"
                        print(f'发送ack响应：{data}')
                        self.netty_client.send(str.encode(data))

                        # 发送10010
                        starttime3 = int(time.time())
                        z_mngSN += 1
                        # todo 10010 power-report
                        payload = "req=10010?msgSN=" + str(
                            z_mngSN).strip() + "&" + z_mngId.strip() + "&dcode=" + z_dcode + "&power=0&start=" + str(
                            starttime3) + "&end=" + str(starttime3) + "&index=0&sign=88f4" + "\r\n"
                        self.netty_client.send(str.encode(payload))
                        print(f"桩 send 10010 :{str.encode(payload)}")
                        time.sleep(SECS)

                        # req=102?msgSN=86169 &mngId=00037f104905 &mcode=2049052& dcode=0000000325001002& status=WAITING
                        # &cv=45163&current=0&pwm=0&ele=0&dsc=NEW_STA#32#28&sign=50b7

                        # 发送102 status-power
                        sql = "select * from t_charge_module_device where moduleId=" + '"' + (
                            z_moduleId.split('=', 1)[1]).strip() + '"' \
                              + " limit 1;"
                        ress = self.db.select_sql(sql)
                        z_mngSN += 1
                        payload = "req=102?msgSN=" + str(z_mngSN).strip() + '&' + z_mngId.strip() + "&mcode=" + str(
                            ress[0]["moduleCode"]) + "&dcode=" + \
                                  z_dcode + "status=WAITING&cv=45163&current=0&pwm=0&ele=0&dsc=NEW_STA#32#28&sign=50b7" + '\r\n'
                        self.netty_client.send(str.encode(payload))
                        print(f"桩 send 102 :{str.encode(payload)}")

                        # 103 detect-report
                        # req=103?msgSN=11&mngId=00037f104905&moduleId=00037f1049051&dcode=0000000325025742&type=0000&chargeTime=0&btvol=36&status=-1&sign=2151
                        z_mngSN += 1
                        payload = 'req=103?msgSN=' + str(
                            z_mngSN).strip() + '&' + z_mngId.strip() + '&' + z_moduleId + '&dcode=' + \
                                  (z_message_list[7].split('=', 1))[
                                      1] + '&type=0000&chargeTime=0&btvol=48&status=-1&sign=2151' + '\r\n'

                        self.netty_client.send(str.encode(payload))
                        print(f"桩 send 103 :{str.encode(payload)}")
                        time.sleep(SECS)

                        z_mngSN += 1
                        #  101 charger-report
                        payload = 'req=101?msgSN=' + str(
                            z_mngSN).strip() + '&' + z_mngId.strip() + '&' + z_moduleId + '&' + z_sessionId + '&status=1&electricityConsumption=0&chargeTime=1&sign=39f7' + '\r\n'
                        self.netty_client.send(str.encode(payload))
                        print(f"桩 send 101 :{str.encode(payload)}")
                        time.sleep(SECS)

                        z_mngSN += 1
                        payload = 'req=100?msgSN=' + str(
                            z_mngSN).strip() + '&' + z_mngId_all.strip() + '&errorId=10003&moduleId=-1&sign=4a31' + '\r\n'
                        self.netty_client.send(str.encode(payload))
                        print(f"桩 send 100 :{str.encode(payload)}")

                        z_mngSN += 1
                        payload = "req=100?msgSN=" + str(
                            z_mngSN).strip() + "&" + z_mngId_all.strip() + "&errorId=10000&moduleId=-1&sign=62ed" + '\r\n'
                        self.netty_client.send(str.encode(payload))
                        print(f"桩 send 100 :{str.encode(payload)}")
                        time.sleep(SECS)

                        sql = "select * from t_charge_module_device where moduleId=" + '"' + (
                            z_moduleId.split('=', 1)[1]).strip() + '"' \
                              + " limit 1;"
                        ress = self.db.select_sql(sql)
                        z_mngSN += 1
                        payload = "req=102?msgSN=" + str(z_mngSN).strip() + "&" + z_mngId_all.strip() + "&mcode=" + str(
                            ress[0][
                                "moduleCode"]) + "&dcode=" + z_dcode + "&status=INIDAL&bpvol=39177&dsc=NEW_STA#32#29&sign=a9c4" + '\r\n'
                        self.netty_client.send(str.encode(payload))
                        print(f"桩 send 102 :{str.encode(payload)}")
                        time.sleep(SECS)


                    elif z_op == '0':
                        # 'req=10002?sign=sign&pileType=7048&operation=0&maxElectricity=0&maxChargeTime=0&moduleId=00037f1049051&msgSN=66&sessionId=0000000325025742&mngId=00037f104905
                        z_mngSN = int(msgSN)
                        payload = {"errorCode": 0, "msgSN": z_mngSN}
                        # 一定要加\r\n 代表结束
                        data = json.dumps(payload) + "\r\n"
                        self.netty_client.send(str.encode(data))
                        print("接收到了关单的消息，响应给服务器ACK")

                        # todo status-report
                        # req=102?msgSN=16&mngId=00037f104905&mcode  =2049051&dcode=0000000325025742&status=INITIAL&btvol=37821&dsc=TERM_EX#32#29&sign=f31e
                        z_mngSN += 1
                        sql = "select * from t_charge_module_device where moduleId=" + '"' + str(
                            (z_message_list[5].split('=', 1))[1]) + '"' + " limit 1;"
                        ress = self.db.select_sql(sql)
                        payload = 'req=102?msgSN=' + str(z_mngSN).strip() + '&' + z_mngId_all.strip() + "&mcode=" + str(
                            ress[0]["moduleCode"]) + "&dcode=" + \
                                  z_dcode + "&status=INITIAL&btvol=37821&dsc=TERM_EX#32#29&sign=f31e" + "\r\n"

                        self.netty_client.send(str.encode(payload))
                        print(f"桩 send 102 :{str.encode(payload)}")
                        time.sleep(SECS)
                        z_mngSN += 1
                        # todo  charger-report
                        # req=101?msgSN=17&mngId=00037f104905&modu leId=00037f1049051&sessionId=0000000325025742&status=5&electricityConsumption=0&chargeTime=40&sign=0201
                        payload = "req=101?msgSN=" + str(
                            z_mngSN).strip() + "&" + z_mngId_all.strip() + "&" + z_moduleId + "&" + z_sessionId + "&status=5&electricityConsumption=8&chargeTime=550&sign=344a" + "\r\n"

                        self.netty_client.send(str.encode(payload))
                        print(f"桩 send 101 :{str.encode(payload)}")
                        time.sleep(SECS)

                        # todo power-report
                        z_mngSN += 1
                        # req=10010?msgSN=18&mngId=00037f104905&dcode=0000000325025742&power=14&start=1702024433&end=1702024473&index=1&sign=8d93
                        payload = "req=10010?msgSN=" + str(
                            z_mngSN).strip() + "&" + z_mngId_all.strip() + "&dcode=" + z_dcode + "&power=200&start=" + str(
                            int(time.time() - 600)) + "&end=" + str(int(time.time())) + "&index=1&sign=88f4" + "\r\n"
                        self.netty_client.send(str.encode(payload))
                        print(f"桩 send 10010 :{str.encode(payload)}")

            else:
                time.sleep(SECS)
                print('没有接收到消息！')


    def reg_device_b40(self, mngid):
        #  6口桩注册
        payload = "req=1?msgSN=6&mngId=" + mngid + "&model=XLR_B40&ver=V4.09.078&bret=1&sign=ff12"
        self.netty_client.send(payload.encode('utf-8'))
        print(f"桩注册设备消息 reg_device:'{mngid}'")


    def reg_device_b66(self,mngid):
        # 3口大功率  400061
        payload = "req=1?msgSN=6&mngId=" + mngid + "&model=XLR_B66&ver=V4.09.04&bret=1&sign=ff12"
        self.netty_client.send(payload.encode('utf-8'))
        print(f"桩注册设备消息 reg_device:'{mngid}'")



    def reg_device_g15(self, mngid):
        # netty 柜 注册
        payload = "req=1?msgSN=1&mngId=" + mngid + "&model=XLR_G15&ver=V4.09.078&bret=1&sign=5008"
        self.netty_client.send(payload.encode('utf-8'))
        print(f"柜注册设备消息 reg_device:'{mngid}'")



if __name__ == '__main__':

    netty_client =NettyThread('00037f601256,10')
    netty_client.start()

